﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;
using System.IO;
using System.Diagnostics;


namespace NaviQuest_v2
{
    public partial class NaviControl : Form
    {
        /*------------NaviQuest Property Definitions ------------*/
        #region

        /*------------Assembly+File Version Info------------*/
        #region

        //Define Assembly and Internal Resources
        public static Assembly assembly = Assembly.GetExecutingAssembly();
        public FileVersionInfo ProgramInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
        
        #endregion

        /*------------Misc Variable Definitions------------*/
        #region

        //Define Tooltip for some info
        public ToolTip tooltip = new ToolTip();

        public int start_npc_count = 0;

        //Define Temp Variables
        public Int32 tempID { get; set; }

        //Define a switch to engage/disengage the NaviControl memory collector
        //set it to on by default
        public bool mem_collector_engaged = true;

        //Define Variables for common functions
        public string first_time = Properties.Settings.Default.first_use;

        #endregion

        /*------------ Quest Related Variables ------------*/
        #region

        /*--------Basic Variables--------*/
        #region
        public Int32 id { get; set; }
        public String name { get; set; }
        public Int32 repeatable { get; set; }
        public Int32 time_limit_type { get; set; }
        public Int32 time_limit { get; set; }
        public Int32 limit_asura { get; set; }
        public Int32 limit_deva { get; set; }
        public Int32 limit_gaia { get; set; }
        public Int32 limit_fighter { get; set; }
        public Int32 limit_magician { get; set; }
        public Int32 limit_summoner { get; set; }
        public Int32 limit_hunter { get; set; }
        public String type { get; set; }
        public String script_start_text { get; set; }
        public String script_end_text { get; set; }
        public String start_desc { get; set; }
        public String mid_desc { get; set; }
        public String end_desc { get; set; }
        #endregion

        /*--------NPC Variables--------*/
        #region
        public Int32 npc1_id { get; set; }
        public String npc1_name { get; set; }
        public String npc1_contact_script { get; set; }
        public Int32 npc1_x { get; set; }
        public Int32 npc1_y { get; set; }

        public Int32 npc2_id { get; set; }
        public String npc2_name { get; set; }
        public String npc2_contact_script { get; set; }
        public Int32 npc2_x { get; set; }
        public Int32 npc2_y { get; set; }

        public Int32 npc3_id { get; set; }
        public String npc3_name { get; set; }
        public String npc3_contact_script { get; set; }
        public Int32 npc3_x { get; set; }
        public Int32 npc3_y { get; set; }

        public Int32 end_npc_id { get; set; }
        public String end_npc_name { get; set; }
        public String end_npc_contact_script { get; set; }
        public Int32 end_npc_x { get; set; }
        public Int32 end_npc_y { get; set; }
        #endregion

        /*-------Objective Variables--------*/
        #region
        public Int32 quest_obj_id1;
        public String quest_obj_name1;
        public String quest_obj_desc1;
        public Int32 quest_obj_amt1;
        public Int32 quest_obj_id2;
        public String quest_obj_name2;
        public String quest_obj_desc2;
        public Int32 quest_obj_amt2;
        public Int32 quest_obj_id3;
        public String quest_obj_name3;
        public String quest_obj_desc3;
        public Int32 quest_obj_amt3;
        public Int32 quest_obj_id4;
        public String quest_obj_name4;
        public String quest_obj_desc4;
        public Int32 quest_obj_amt4;
        public Int32 quest_obj_id5;
        public String quest_obj_name5;
        public String quest_obj_desc5;
        public Int32 quest_obj_amt5;
        public Int32 quest_obj_id6;
        public String quest_obj_name6;
        public String quest_obj_desc6;
        public Int32 quest_obj_amt6;
        #endregion

        #endregion

        /*------------Default Search Filters------------*/
        #region
        //Define Default Search Filter Options
        public bool search_by_id = Properties.Settings.Default.search_by_id;
        public bool search_by_name = Properties.Settings.Default.search_by_name;
        public bool search_by_lv = Properties.Settings.Default.search_by_lv;
        public bool search_by_summary = Properties.Settings.Default.search_by_summary;
        #endregion

        /*------------List Entry Totals------------*/
        #region

        //Define Individual Totals
        public static int quest_total = 0;
        public static int questlink_total = 0;
        public static int quest_basic_total = 0;
        public static int quest_npc_total = 0;
        public static int quest_item_objective_total = 0;
        
        #endregion

        /*------------Background Workers------------*/
        #region
        //Define Background Workers 
        public BackgroundWorker ui_updater = new BackgroundWorker();
        public BackgroundWorker list_reader = new BackgroundWorker();
        public BackgroundWorker npc_info_collector = new BackgroundWorker();
        public BackgroundWorker item_objective_collector = new BackgroundWorker();
        public BackgroundWorker mem_usage_collector = new BackgroundWorker();
        #endregion

        /*------------Embedded Resources------------*/
        #region
        //Define the embedded resources for reading file line total
        public static StreamReader internal_quest_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Quest.txt"));
        public static StreamReader internal_questlink_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.QuestLink.txt"));
        public static StreamReader internal_basic_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Basic.txt"));
        public static StreamReader internal_npc_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.NPC.txt"));

        public static StreamReader internal_item_objective_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Item_Objective.txt"));
        public static StreamReader internal_monster_objective_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Monster_Objective.txt"));
        public static StreamReader internal_skill_objective_total_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Skill_Objective.txt"));

        //Define the embedded resources for reading file contents
        public StreamReader internal_quest_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Quest.txt"));
        public StreamReader internal_questlink_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.QuestLink.txt"));
        public StreamReader internal_basic_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Basic.txt"));
        public StreamReader internal_npc_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.NPC.txt"));

        public StreamReader internal_item_objective_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Item_Objective.txt"));
        public StreamReader internal_monster_objective_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Monster_Objective.txt"));
        public StreamReader internal_skill_objective_reader = new StreamReader(assembly.GetManifestResourceStream("NaviQuest_v2.Lists.Skill_Objective.txt"));
        #endregion

        /*--------------DataTables--------------*/
        #region

        public DataTable quest_table = new DataTable("quests");
        public DataTable questlink_table = new DataTable("questlink");
        public DataTable basic_table = new DataTable("basic");
        public DataTable npc_table = new DataTable("npc");
        public DataTable npc_table2 = new DataTable("npc2");
        public DataTable npc_table3 = new DataTable("npc3");
        public DataTable npc_table_end = new DataTable("end_npc");
        public DataTable mob_table = new DataTable("mob");
        public DataTable item_objectives_table = new DataTable("item_objectives");
        public DataTable item_objectives_table1 = new DataTable("item_objectives1");
        public DataTable item_objectives_table2 = new DataTable("item_objectives2");
        public DataTable item_objectives_table3 = new DataTable("item_objectives3");
        public DataTable item_objectives_table4 = new DataTable("item_objectives4");
        public DataTable item_objectives_table5 = new DataTable("item_objectives5");


        public DataTable monster_objectives_table = new DataTable("monster_objectives");
        public DataTable skill_objectives_table = new DataTable("skill_objectives");
       
        #endregion

        /*--------------DataRows--------------*/
        #region

        //Define basic info datarow
        public DataRow basic_result;
        public DataRow npc_result;
        public DataRow objective_result;

        #endregion

        #endregion

        /*------------NaviQuest Load Events ------------*/
        #region
        //Initial Load Events
        public NaviControl()
        {
            //Initialize NaviQuest Components
            InitializeComponent();
            //Initialize Some custom action handlers
            CustomEventHandlers();
        }

        //This occurs on NaviQuest's load event
        public void NaviControl_Load(object sender, EventArgs e)
        {            
            String ProgramName = ProgramInfo.OriginalFilename.Replace(".exe", "");
            String ProgramVersion = " v" + ProgramInfo.FileVersion;

            //Initialize the log 
            NaviControl_Update_Log("initial", 0, "==================================================");
            NaviControl_Update_Log("text", 1,  ProgramName + ProgramVersion + " initializing...");
            NaviControl_Update_Log("text", 1, "==================================================");
            NaviControl_Update_Log("", 1, "");

            //Issue a log message
            NaviControl_Update_Log("text", 1, "Launching Self Tests");

            //If chk returns true || First Use
            if (NaviControl_First_Use_Check() == "true")
            {
                NaviControl_Update_Log("text", 1, " - First Launch Detected!");
                NaviControl_Update_Log("text", 1, " -- Showing Welcome Message");
                NaviControl_Update_Log("", 1, "");

                //Define the form to be used as our info popup
                Popup sys_pop = new Popup();
                //Show the popup as dialog so it must be "ok'd"
                sys_pop.ShowDialog();
                //After the Welcome Popup is closed
                //We should focus NaviControl to the "Settings" tab
            }

            //The Lists have been loaded, begin collecting info
            //before enabling recurring collecting
            mem_usage_collector.DoWork += NaviControl_Memory_Collector;
            mem_usage_collector.RunWorkerAsync();

            //Send log message
            NaviControl_Update_Log("text", 1, "Memory Usage Collector Launched");

            //Launch NaviControl Lists Loader
            //As a BackGround Worker 
            list_reader.DoWork += NaviControl_Internal_List_Loader;
            list_reader.RunWorkerAsync();

            NaviControl_Update_Log("text", 1, "Internal List Loader Launched");

            //Set Default Search Filter Option
            //based on the last option picked
            NaviControl_Set_Search_Filter();
        }
        #endregion

        /*------------NaviQuest Form Interactions ------------*/
        #region
        //NaviControl's Search Menu was double-clicked
        public void quest_list_DoubleClick(object sender, EventArgs e)
        {
            GC.Collect();

            //Define a temporary Quest ID for further
            //functions
            tempID = Convert.ToInt32(quest_list.SelectedRows[0].Cells[0].Value);

            //To avoid bugs check if the list reader is busy first
            if (list_reader.IsBusy)
            {
                //If so error out and continue loading
                MessageBox.Show(ParentForm, "Please wait until NaviQuest is finished loading", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else //Else
            {
                //Define a local Background Worker to Collect 
                //quest info
                BackgroundWorker info_collector = new BackgroundWorker();

                //This action may be repeated so for safety,
                //dispose the worker thread before launching
                info_collector.Dispose();

                //Launch Basic Info Collector as Background Worker
                info_collector.DoWork += NaviControl_Collect_Quest_Info;
                info_collector.RunWorkerAsync();

                //Bring the "Basic Info" tab into focus
                NaviControl_Tab_Focus(1);

                //To reduce Memory Stress lets clear any memory garbage
                GC.Collect();
            }          
        }

        //Open Default Browser and Navigate to Teal Sky Facebook
        private void NaviQuest_TealSky_DEV_LINK_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process.Start("http://facebook.com/TealSkyDevelopment");
        }
        #endregion

    }
}
